package com.anolesoft.yr.mbus.part.service.impl;

import com.anolesoft.yr.exception.ServiceException;
import com.anolesoft.yr.mbus.part.dto.PartModelDTO;
import com.anolesoft.yr.mbus.part.dto.PartModelTreeDynamicQueryDTO;
import com.anolesoft.yr.mbus.part.dto.PartModelTreeQueryDTO;
import com.anolesoft.yr.mbus.part.entity.PartModelDO;
import com.anolesoft.yr.mbus.part.entity.PartModelTreeDynamicQueryDO;
import com.anolesoft.yr.mbus.part.entity.PartModelTreeQueryDO;
import com.anolesoft.yr.mbus.part.mapper.PartModelMapper;
import com.anolesoft.yr.mbus.part.mapper.PartModelTreeDynamicQueryMapper;
import com.anolesoft.yr.mbus.part.mapper.PartModelTreeQueryMapper;
import com.anolesoft.yr.mbus.part.service.PartModelService;
import com.anolesoft.yr.util.CustomBeanUtils;
import com.anolesoft.yr.util.PageData;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author zhj
 * @date 2020/8/11 15:50
 */
@Service("partModelServiceImpl")
public class PartModelServiceImpl implements PartModelService {
    @Autowired
    private PartModelMapper partModelMapper;
    @Autowired
    private PartModelTreeQueryMapper partModelTreeQueryMapper;
    @Autowired
    private PartModelTreeDynamicQueryMapper partModelTreeDynamicQueryMapper;

    private void checkUnique(PartModelDTO partModelDTO, boolean isModify) {
        String objuid = partModelDTO.getObjuid();
        String partCode = partModelDTO.getPartCode();
        if (isModify) {
            if (partModelMapper.checkUniqueForPartCodeUpdate(partCode, objuid) > 0) {
                throw new ServiceException("配件编号已存在");
            }
        } else {
            if (partModelMapper.checkUniqueForPartCode(partCode) > 0) {
                throw new ServiceException("配件编号已存在");
            }
        }
    }

    @Transactional
    @Override
    public int create(PartModelDTO partModelDTO) {
        checkUnique(partModelDTO, false);

        return partModelMapper.insert(PartModelDO.builder()
                .objuid(partModelDTO.getObjuid())
                .quantity(partModelDTO.getQuantity())
                .unit(partModelDTO.getUnit())
                .partSpecification(partModelDTO.getPartSpecification())
                .partCode(partModelDTO.getPartCode())
                .partModel(partModelDTO.getPartModel())
                .viceModel(partModelDTO.getViceModel())
                .partName(partModelDTO.getPartName())
                .partBrand(partModelDTO.getPartBrand())
                .partTypeUid(partModelDTO.getPartTypeUid())
                .factoryCode(partModelDTO.getFactoryCode())
                .remark(partModelDTO.getRemark())
                .modifyUserUid(partModelDTO.getModifyUserUid())
                .createUserUid(partModelDTO.getCreateUserUid())
                .createTime(partModelDTO.getCreateTime())
                .deleteFlag(partModelDTO.getDeleteFlag())
                .modifyTime(partModelDTO.getModifyTime())
                .parentPartModelUid(partModelDTO.getParentPartModelUid())
                .build());
    }

    @Transactional
    @Override
    public int modify(PartModelDTO partModelDTO) {
        checkUnique(partModelDTO, true);
        PartModelDO partModelDO = partModelMapper.selectOneById(partModelDTO.getObjuid());
        if (partModelDO == null) {
            partModelDO = PartModelDO.builder().build();
        } else {
            partModelDO.setCreateTime(partModelDTO.getCreateTime());
            partModelDO.setCreateUserUid(partModelDTO.getCreateUserUid());
            partModelDO.setDeleteFlag(partModelDTO.getDeleteFlag());
            partModelDO.setFactoryCode(partModelDTO.getFactoryCode());
            partModelDO.setModifyTime(partModelDTO.getModifyTime());
            partModelDO.setModifyUserUid(partModelDTO.getModifyUserUid());
            partModelDO.setObjuid(partModelDTO.getObjuid());
            partModelDO.setPartBrand(partModelDTO.getPartBrand());
            partModelDO.setPartCode(partModelDTO.getPartCode());
            partModelDO.setPartModel(partModelDTO.getPartModel());
            partModelDO.setViceModel(partModelDTO.getViceModel());
            partModelDO.setPartName(partModelDTO.getPartName());
            partModelDO.setPartSpecification(partModelDTO.getPartSpecification());
            partModelDO.setPartTypeUid(partModelDTO.getPartTypeUid());
            partModelDO.setQuantity(partModelDTO.getQuantity());
            partModelDO.setRemark(partModelDTO.getRemark());
            partModelDO.setUnit(partModelDTO.getUnit());
            partModelDO.setParentPartModelUid(partModelDTO.getParentPartModelUid());
        }
        return partModelMapper.update(partModelDO);
    }

    @Transactional
    @Override
    public int remove(String id) {
        return partModelMapper.delete(id);
    }

    @Override
    public int removeBatch(List<String> ids) {
        int res = 0;
        for (String id : ids) {
            res += partModelMapper.delete(id);
        }
        return res;
    }

    @Override
    public List<PartModelDTO> selectAll() {
        return partModelMapper.selectAll().stream().map(t -> CustomBeanUtils.partModelDO2DTO(t)).collect(Collectors.toList());
    }

//    public static PartModelDTO do2dto(PartModelDO t) {
//        PartTypeDO partType = t.getPartType();
//        PartTypeDTO partTypeDTO = null;
//        if(partType != null){
//            partTypeDTO =  PartTypeDTO.builder()
//                    .createTime(partType.getCreateTime())
//                    .createUserUid(partType.getCreateUserUid())
//                    .deleteFlag(partType.getDeleteFlag())
//                    .factoryCode(partType.getFactoryCode())
//                    .modifyTime(partType.getModifyTime())
//                    .modifyUserUid(partType.getModifyUserUid())
//                    .objuid(partType.getObjuid())
//                    .remark(partType.getRemark())
//                    .typeCode(partType.getTypeCode())
//                    .typeName(partType.getTypeName())
//                    .build();
//        }else {
//            partTypeDTO = new PartTypeDTO();
//        }
//        PartModelDTO partModelDTO = PartModelDTO.builder()
//                .objuid(t.getObjuid())
//                .quantity(t.getQuantity())
//                .unit(t.getUnit())
//                .partSpecification(t.getPartSpecification())
//                .partCode(t.getPartCode())
//                .partModel(t.getPartModel())
//                .partName(t.getPartName())
//                .partBrand(t.getPartBrand())
//                .partTypeUid(t.getPartTypeUid())
//                .factoryCode(t.getFactoryCode())
//                .remark(t.getRemark())
//                .modifyUserUid(t.getModifyUserUid())
//                .createUserUid(t.getCreateUserUid())
//                .createTime(t.getCreateTime())
//                .deleteFlag(t.getDeleteFlag())
//                .modifyTime(t.getModifyTime())
//                .partType(partTypeDTO)
//                .build();
//        return partModelDTO;
//    }

    @Override
    public PageData<List<PartModelDTO>> selectAll(Integer limit, Integer curr) {
        Page<PartModelDO> page = new Page<>(curr, limit);
        List<PartModelDTO> partModelDTOs = partModelMapper.selectPageAll(page).stream().map(t -> CustomBeanUtils.partModelDO2DTO(t)).collect(Collectors.toList());
        return new PageData<>((int) page.getTotal(), partModelDTOs);
    }

    @Override
    public Optional<PartModelDTO> selectOneById(String id) {
        PartModelDO partModelDO = partModelMapper.selectOneById(id);
        if (partModelDO != null) {
            return Optional.of(CustomBeanUtils.partModelDO2DTO(partModelDO));
        }
        return Optional.empty();
    }

    @Override
    public List<PartModelDTO> selectList(PartModelDTO partModelDTO) {
        PartModelDO partModelDO = buildCondition(partModelDTO);
        return partModelMapper.selectList(partModelDO).stream().map(t -> CustomBeanUtils.partModelDO2DTO(t)).collect(Collectors.toList());
    }

    private PartModelDO buildCondition(PartModelDTO partModelDTO) {
        return PartModelDO.builder()
                .objuid(partModelDTO.getObjuid())
                .quantity(partModelDTO.getQuantity())
                .unit(partModelDTO.getUnit())
                .partSpecification(partModelDTO.getPartSpecification())
                .partCode(partModelDTO.getPartCode())
                .partModel(partModelDTO.getPartModel())
                .viceModel(partModelDTO.getViceModel())
                .partName(partModelDTO.getPartName())
                .partBrand(partModelDTO.getPartBrand())
                .partTypeUid(partModelDTO.getPartTypeUid())
                .factoryCode(partModelDTO.getFactoryCode())
                .remark(partModelDTO.getRemark())
                .modifyUserUid(partModelDTO.getModifyUserUid())
                .createUserUid(partModelDTO.getCreateUserUid())
                .createTime(partModelDTO.getCreateTime())
                .deleteFlag(partModelDTO.getDeleteFlag())
                .modifyTime(partModelDTO.getModifyTime())
                .parentPartModelUid(partModelDTO.getParentPartModelUid())
                .build();
    }

    @Override
    public PageData<List<PartModelDTO>> selectList(PartModelDTO partModelDTO, Integer limit, Integer curr) {
        PartModelDO partModelDO = buildCondition(partModelDTO);
        Page<PartModelDO> page = new Page<>(curr, limit);
        List<PartModelDO> partModelDOS = partModelMapper.selectPageList(partModelDO, page);
        List<PartModelDTO> partModelDTOS = partModelDOS.stream().map(t -> CustomBeanUtils.partModelDO2DTO(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), partModelDTOS);
    }

    @Override
    public PageData<List<PartModelDTO>> selectComboxList(PartModelDTO partModelDTO, Integer limit, Integer curr) {
        PartModelDO partModelDO = buildCondition(partModelDTO);
        Page<PartModelDO> page = new Page<>(curr, limit);
        List<PartModelDO> partModelDOS = partModelMapper.selectComboxList(partModelDO, page);
        List<PartModelDTO> partModelDTOS = partModelDOS.stream().map(t -> CustomBeanUtils.partModelDO2DTO(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), partModelDTOS);
    }

    @Override
    public List<PartModelTreeQueryDTO> getTree(String parentId) {
        List<PartModelTreeQueryDO> partModelTreeQueryDOS = partModelTreeQueryMapper.selectTree(parentId);
        return getChildren(partModelTreeQueryDOS);
    }

    @Override
    public PageData<List<PartModelTreeDynamicQueryDTO>> getDynamicTreePage(String parentId, Integer limit, Integer curr) {
        Page<PartModelTreeDynamicQueryDO> page = new Page<>(curr, limit);
        List<PartModelTreeDynamicQueryDO> partModelTreeDynamicQueryDOS = partModelTreeDynamicQueryMapper.selectTreePage(parentId, page);
        List<PartModelTreeDynamicQueryDTO> dtos = partModelTreeDynamicQueryDOS.stream().map(t ->
                PartModelTreeDynamicQueryDTO.builder()
                        .objuid(t.getObjuid())
                        .parentPartModelUid(t.getParentPartModelUid())
                        .partBrand(t.getPartBrand())
                        .partCode(t.getPartCode())
                        .partModel(t.getPartModel())
                        .viceModel(t.getViceModel())
                        .partName(t.getPartName())
                        .partSpecification(t.getPartSpecification())
                        .partType(CustomBeanUtils.partTypeDO2DTO(t.getPartType()))
                        .partTypeUid(t.getPartTypeUid())
                        .quantity(t.getQuantity())
                        .unit(t.getUnit())
                        .hasChild(t.getHasChild())
                        .build()).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), dtos);
    }

    @Override
    public List<PartModelTreeDynamicQueryDTO> getDynamicTree(String parentId) {
        return partModelTreeDynamicQueryMapper.selectTree(parentId).stream().map(t ->
                PartModelTreeDynamicQueryDTO.builder()
                        .objuid(t.getObjuid())
                        .parentPartModelUid(t.getParentPartModelUid())
                        .partBrand(t.getPartBrand())
                        .partCode(t.getPartCode())
                        .partModel(t.getPartModel())
                        .viceModel(t.getViceModel())
                        .partName(t.getPartName())
                        .partSpecification(t.getPartSpecification())
                        .partType(CustomBeanUtils.partTypeDO2DTO(t.getPartType()))
                        .partTypeUid(t.getPartTypeUid())
                        .quantity(t.getQuantity())
                        .unit(t.getUnit())
                        .hasChild(t.getHasChild())
                        .build()).collect(Collectors.toList());
    }

    private List<PartModelTreeQueryDTO> getChildren(List<PartModelTreeQueryDO> children) {
        return children.stream().map(t -> {
            PartModelTreeQueryDTO partModelTreeQueryDTO = PartModelTreeQueryDTO.builder()
                    .objuid(t.getObjuid())
                    .parentPartModelUid(t.getParentPartModelUid())
                    .partBrand(t.getPartBrand())
                    .partCode(t.getPartCode())
                    .partModel(t.getPartModel())
                    .viceModel(t.getViceModel())
                    .partName(t.getPartName())
                    .partSpecification(t.getPartSpecification())
                    .partType(CustomBeanUtils.partTypeDO2DTO(t.getPartType()))
                    .partTypeUid(t.getPartTypeUid())
                    .quantity(t.getQuantity())
                    .unit(t.getUnit())
                    .build();
            if (t.getChildren().size() > 0) {
                partModelTreeQueryDTO.setChildren(getChildren(t.getChildren()));
            } else {
                partModelTreeQueryDTO.setChildren(new ArrayList<>(10));
            }
            return partModelTreeQueryDTO;
        }).collect(Collectors.toList());
    }
}
